# 导入必要的模块
import json
import time
from typing import Callable, Type
import tornado.ioloop
import tornado.web
import tornado.websocket

from TextSearch.app.configs import AppConfig
from TextSearch.utils.tasks import BackgroundTask
from ..services.base import BaseWebSocketHandler, TornadoWebSocketContext
from ..services.text_indexing import (
    TextIndexingWebSocketHandler,
    TextSearchingWebSocketHandler,
    open_file,
)
from ..services.git_repos_indexing import (
    GitReposIndexingWSHandler,
    config_git_repo_searching_paths,
)
import threading
from ..api.vscode import open_vscode_folder_path


class GetConfigItemHandler(tornado.web.RequestHandler):
    def get(self):
        return self.write(
            {
                "configItemData": AppConfig().__dict__.get(
                    self.get_argument("configItemName", None)
                )
            }
        )


class UpdateConfigItemHandler(tornado.web.RequestHandler):
    def post(self):
        # 获取json格式传输的body
        data = json.loads(self.request.body)
        print(data)
        configItemName = data.get("configItemName", None)
        configItemValue = data.get("configItemValue", None)
        print("updated configs", configItemName, configItemValue)
        AppConfig().update_config_item(configItemName, configItemValue)
        return self.write({"status": "success"})


class OpenSearchResultHandler(tornado.web.RequestHandler):
    def post(self):
        data = json.loads(self.request.body)
        # {"file": 找到的文件的路径, "data": 文件中含有关键词的文本, "search": 关键词}
        open_file(data["file"], data["text"], data["search"])
        return self.write({"status": "success"})


def create_general_http_handler_cls(
    handler_get: Callable[[tornado.web.RequestHandler], None] = None,
    handler_post: Callable[[tornado.web.RequestHandler], None] = None,
):
    class _general_http_handler_cls(tornado.web.RequestHandler):
        def get(self):
            if handler_get is not None:
                ret = handler_get(**self.request.arguments)
                self.write(ret)
            else:
                self.set_status(405)
                self.write({"status": "error", "message": "No GET handler defined"})

        def post(self):
            if handler_post is not None:
                ret = handler_post(**json.loads(self.request.body))
                self.write(ret)
            else:
                self.set_status(405)
                self.write({"status": "error", "message": "No POST handler defined"})

    return _general_http_handler_cls


def create_websocket_handler_cls(handler_type: Type[BaseWebSocketHandler]):
    class _websocket_handler_cls(tornado.websocket.WebSocketHandler):
        def open(self):
            self.handler = handler_type(
                TornadoWebSocketContext(tornado.ioloop.IOLoop.current(), self)
            )
            params = {k: self.get_argument(k) for k in self.request.arguments.keys()}
            self.handler.on_open(**params)

        def on_message(self, message):
            print("收到消息:", message)
            self.handler.on_message(message)

        def on_close(self):
            self.handler.on_close()

        def check_origin(self, origin):
            return True

    return _websocket_handler_cls


# 创建Tornado应用
def make_app():
    return tornado.web.Application(
        [
            (
                r"/api/text_search/run_text_index",
                create_websocket_handler_cls(TextIndexingWebSocketHandler),
            ),
            (
                r"/api/configs/get_config_item",
                GetConfigItemHandler,
            ),
            (
                r"/api/configs/update_config_item",
                UpdateConfigItemHandler,
            ),
            (
                r"/api/text_search/run_text_search",
                create_websocket_handler_cls(TextSearchingWebSocketHandler),
            ),
            (
                r"/api/text_search/open_search_result",
                OpenSearchResultHandler,
            ),
            (
                r"/api/git_repo_search/run_repo_search",
                create_websocket_handler_cls(GitReposIndexingWSHandler),
            ),
            (
                r"/api/git_repo_search/set_search_paths",
                create_general_http_handler_cls(
                    handler_post=config_git_repo_searching_paths
                ),
            ),
            (
                r"/api/third_party_software/vscode",
                create_general_http_handler_cls(handler_post=open_vscode_folder_path),
            ),
        ],
        debug=True,
    )
